package cn.joybreeze.common.exception;

import cn.joybreeze.common.result.R;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName GlobalExceptionHandler
 * @Description 全局异常捕获
 * @Author Kjwaa
 * @Email 1135274290@qq.com
 * @Date 2021/8/24 14:13
 */

@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * Full authentication is required to access this resource , 403 forbidden 走的异常
     * 形同虚设 根本走不进来
     *
     * @return
     */
    @ExceptionHandler(InsufficientAuthenticationException.class)
    public R requiredAuthentication() {
        return R.error("请登录认证");
    }

    /**
     * 匿名用户访问无权限资源时的异常，403 forbidden 走的竟然不是这个异常
     * 形同虚设 根本走不进来
     *
     * @return
     */
    @ExceptionHandler(AuthenticationException.class)
    public R requestToLogin(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
        return R.error("未登录");
    }

    /**
     * 认证过的用户访问无权限资源时的异常
     * 形同虚设 根本走不进来
     *
     * @return
     */
    @ExceptionHandler(AccessDeniedException.class)
    public R accessDenied(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) {
        return R.error("无权限访问");
    }

    /**
     * 参数校验异常
     *
     * @param ex
     * @param request
     * @param response
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Map<String, String> paramValid(MethodArgumentNotValidException ex, HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return errors;
    }

    @ExceptionHandler(Exception.class)
    public R defaultExceptionHandler(Exception ex, HttpServletRequest request, HttpServletResponse response) {
        return R.error();
    }
}
